package cn.example.demo.modules.house.recommend;

import cn.example.demo.modules.house.entity.HouseType;
import cn.example.demo.modules.house.entity.Region;
import cn.example.demo.modules.house.mapper.HouseTypeMapper;
import cn.example.demo.modules.house.mapper.RegionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Description: 数据维度编码器，将离散的UUID转换为连续的数值特征（例如房间类型ID、地区ID）
 * 常用的方法包括标签编码（Label Encoding）、独热编码（One-Hot Encoding）和嵌入编码（Embedding）。
 * 这里用简单版的标签编码
 *
 * @author Lzx
 * @create 2025/3/22 17:36
 */
@Component
public class DataDimensionEncoder {
    @Autowired
    private HouseTypeMapper houseTypeMapper;
    @Autowired
    private RegionMapper regionMapper;

    // 内存缓存类型映射关系
    /**
     * 房间类型
     */
    private final Map<String, Double> houseTypeEncodingMap = new ConcurrentHashMap<>();
    /**
     * 地区编码
     */
    private final Map<String, Double> regionEncodingMap = new ConcurrentHashMap<>();

    /**
     * 服务启动时加载
     */
    @PostConstruct
    public void init() {
        // 房间类型编码初始化
        initHouseTypeEncodingMap();
        // 地区编码初始化
        initRegionEncodingMap();
    }

    /**
     * 初始化房间类型编码映射器
     */
    protected void initHouseTypeEncodingMap() {
        List<HouseType> allHouseType = houseTypeMapper.selectList(null);
        double step = 1.0 / allHouseType.size(); // 等间距编码
        double currentCode = 0.0;
        for (HouseType type : allHouseType) {
            houseTypeEncodingMap.put(type.getId(), currentCode);
            currentCode += step;
        }
    }

    /**
     * 初始化地区编码映射器
     */
    protected void initRegionEncodingMap() {
        List<Region> allRegion = regionMapper.selectList(null);
        double step = 1.0 / allRegion.size(); // 等间距编码
        double currentCode = 0.0;
        for (Region region : allRegion) {
            regionEncodingMap.put(region.getId(), currentCode);
            currentCode += step;
        }
    }

    /**
     * 编码房间类型
     *
     * @param typeUUID
     * @return
     */
    public double encodeHouseType(String typeUUID) {
        return houseTypeEncodingMap.getOrDefault(typeUUID, 0.0);
    }

    /**
     * 编码地区类型
     *
     * @param typeUUID
     * @return
     */
    public double encodeRegion(String typeUUID) {
        return regionEncodingMap.getOrDefault(typeUUID, 0.0);
    }
}
